﻿using System.Windows;
using Liphofra.Core;
using Liphofra.Core.EventAggregation;
using Liphofra.Mvvm.Navigation;
using Liphofra.Mvvm.Validation;
using Liphofra.Mvvm.ViewModels;
using Microsoft.Phone.Controls;

namespace Liphofra.Mvvm
{
    /// <summary>
    /// A bootstrapping mechanism that can be used to easily configure and set up the whole framework for a Windows Phone application.
    /// Typically the <see cref="Initialize"/> method is invoked early in the application life cycle, for example in the <see cref="Application"/> constructor.
    /// </summary>
    public class Bootstrapper
    {
        private static readonly Bootstrapper _instance = new Bootstrapper();

        private Bootstrapper()
        {
        }

        /// <summary>
        /// Initializes the framework by pre-configuring the important types, i.e.
        /// - the default service locator implementation
        /// - the default event aggregator
        /// - the default view model factory
        /// - the default navigation service, using the specified navigation frame
        /// - the default validation manager
        /// </summary>
        /// <param name="frame">The navigation frame to use for the navigation service.</param>
        public static void Initialize(PhoneApplicationFrame frame)
        {
            _instance.RegisterTypes(frame);
        }

        /// <summary>
        /// Registers the default types.
        /// </summary>
        /// <param name="frame">The phone application frame to use for the navigation service.</param>
        protected virtual void RegisterTypes(PhoneApplicationFrame frame)
        {
            var serviceLocator = ServiceLocator.Instance;

            // event aggregator
            var eventAggregator = new EventAggregator();
            serviceLocator.Register<IEventAggregator>(() => eventAggregator);

            // view model factory
            serviceLocator.Register<IViewModelFactory, ViewModelFactory>();

            // navigation service
            var navigationService = new FrameNavigationService(frame);
            serviceLocator.Register<INavigationService>(() => navigationService);

            // validation manager
            var validationManager = new ValidationManager();
            serviceLocator.Register<IValidationManager>(() => validationManager);
        }
    }
}